#ifndef SRC_INCLUDE_SHYPER_SERVICE_H
#define SRC_INCLUDE_SHYPER_SERVICE_H

#include <asm/siginfo.h>
#include <linux/cdev.h>
#include <linux/device.h>
#include <linux/errno.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/pid.h>
#include <linux/pid_namespace.h>
#include <linux/sched.h>
#include <linux/signal.h>
#include <linux/slab.h>
#include <linux/types.h>
#include <linux/uaccess.h>
#include <linux/vmalloc.h>

#include "util.h"
#include <asm-generic/int-ll64.h>
#include <asm/uaccess.h>
#include <linux/buffer_head.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/jiffies.h>
#include <linux/miscdevice.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>
#include <linux/stat.h>
#include <linux/time.h>
#include <linux/timekeeping.h>
#include <linux/timer.h>
#include <linux/version.h>

#define VM_PAGE_SIZE (0x1000)
#define SPACE_MAX_SIZE ((5 + VM_PAGE_SIZE / 8) * VM_PAGE_SIZE)
#define LOG_BUFFER_BYTES (VM_PAGE_SIZE * 8)
#define VM_NUM 1
#define VM_NUM_MAX (8)

typedef enum {
    IOCTL_RECEIVE_MESSAGE = 0x0000,
    IOCTL_SEND_MESSAGE = 0x0001,
    IOCTL_TEST_SERVICE = 0x0210,
} MODULE_IOCTL_CMD;

struct hvc_irq_arg {
    u64 fid;
    u64 event;
};

struct msg_data {
    u64 fid;
    u64 event;
    u64 src;
    u64 size;
    u64 idx;
    u64 fin;
    // char data[];
};

typedef enum {
    RECEIVE_MESSAGE,
    PRINT_MESSAGE,
} IRQ_HANDLER_TYPE;

typedef enum {
    WAIT,
    RECEIVE,
} RECEIVE_STATE;

struct shyper_dev {
    struct cdev cdev;
    char *cfg_queue;
    char *send_queue;
    u64 receive_queue[8];
    u32 receive_idx[4];
    u64 send_idx[4];
    u64 usr_pid;
    u64 vmid;
    struct task_struct *current_task;
    char *cfg_ptr;
    struct ring_queue *usr_arg_queue;
};

extern struct shyper_dev shyper_dev;
extern struct timer_list kernel_timer;
extern struct timer_list guset_os_timer[VM_NUM];
//extern struct miscdevice remap_pfn_misc

extern dev_t devno;
extern int irqno;
extern u64 cur_vm_id;

irqreturn_t irq_handler(int irq, void *handle);
irqreturn_t blk_handler(int irq, void *handle);

void get_irqno_from_node_and_register(void);
void register_misc(void);
void deregister_misc(void);
#endif /* SRC_INCLUDE_SHYPER_SERVICE_H */
